﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Gds.Model.ConfigModel.BasicSystemInfo;
using Gds.Model;
using Gds.Model.ConfigModel.LogModel;
using Gds.Utility.Helper;
using Gds.Model.ConfigModel.RealTimeModel;
using System.Collections;
using System.Windows.Input;

namespace Gds.ViewModel.pageViewModel
{
    public class MainViewModel : INotifyPropertyChanged
    {
        #region default param
        public static volatile MainViewModel _instance = new MainViewModel();
        public static object LockHelper = new object();
        public static object LogLockHelper = new object();
        public static MainViewModel Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (LockHelper)
                    {
                        if (_instance == null)
                        {
                            _instance = new MainViewModel();
                        }
                    }
                }
                return _instance;
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        public virtual void OnPropertyChange([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
        #region public Param
        private LocalSystemConfig _localSystemConfig;
        public Model.ConfigModel.BasicSystemInfo.LocalSystemConfig LocalConfig
        {
            get
            {
                if (_localSystemConfig == null || _localSystemConfig.ServerIp == null || _localSystemConfig.ServerIp == string.Empty)
                {
                    ServerConfigViewModel.Instance.LoadLocalConfig();
                    _localSystemConfig = ServerConfigViewModel.Instance.LocalConfig;
                }
                return _localSystemConfig;
            }
        }
        public bool IsAutoRun
        {
            get { return LocalConfig.IsAutoRun; }
        }
        public bool IsMainServer
        {
            get { return LocalConfig.IsMainServer; }
        }
        public bool MainServerIsShutDown = false;
        public bool ExitFlag = false;
        public bool IsNeedReloadConfig = false;
        public bool IsStartCheckToReStart = false;
        private int _backupServerState = -1;
        private int _mainServerState = -1;
        private int _mainServerFailTime = 0;
        private int _backupServerFailTime = 0;
        private int _heartBeatCheckSplit = 10;
        private string _mainserverHeartTime = "";
        private string _backupserverHeartTime = "";
        private int _readSplit = 1000;
        public int ReadSplit
        {
            get { return _readSplit; }
            set { _readSplit = value; OnPropertyChange("ReadSplit"); }
        }
        private Dictionary<int, string> _clientModelPortDic = new Dictionary<int, string>();

        #endregion
        #region Event Param
        /// <summary>
        /// 开启通讯线程事件
        /// </summary>
        public event EventHandler StartTaksEvent;
        /// <summary>
        /// 停止通讯线程
        /// </summary>
        public event EventHandler StopTaksEvent;

        public event EventHandler OpenClentConfigViewEvent;

        private void RunOpenClentConfigViewEvent()
        {
            if (OpenClentConfigViewEvent != null)
            { OpenClentConfigViewEvent(null, null); }
        }
        #endregion
        #region BindingModel
        private bool _serverLinkState;
        private bool _backupserverLinkState;
        private bool _isRunning = false;
        private bool _isWaiting = false;
        private bool _isStopping = false;
        private bool _mainServerNormalFlag = true;
        private bool _isShowHeartBeatLog;
        private bool _isCheckTaskHeartBeat;
        private string _currentMember;
        private AsyncObservableCollection<BasicLogModel> _runLogModels;
        private ObservableCollection<HeartBeatModel> CurHeartBeatModels;
        private ObservableCollection<Model.ConfigModel.SerialPort.EquipSerialPortModel> _equipSerialPorts;
        private ObservableCollection<Model.ConfigModel.Controller.ControllerConfigModel> _controllerConfigModel;
        private ObservableCollection<Model.ConfigModel.GasMeter.GasMeterConfig> _gasMeterConfig;
        private ObservableCollection<Model.TestFunctionModel.TaskStartModel> _taskStartModels;
        private ObservableCollection<UserInfo> _taskUserInfoModels;
        private AsyncObservableCollection<Model.ConfigModel.BasicSystemInfo.UserInfo> _onLineClientList;
        private Dictionary<int, Model.TestFunctionModel.TaskStartModel> _dicTaskStation;
        private Dictionary<string, Model.ConfigModel.RealTimeModel.RealTimeGasPotencyModel> _realTimeGasPotencyModels;
        private Dictionary<string, Model.ConfigModel.GasMeter.AlarmSearchModel> _dicGasState;
        private List<int> _errorTaskList;
        private int _errorTaskListCount;
        public bool ServerLinkState
        {
            get { return _serverLinkState; }
            set { _serverLinkState = value; OnPropertyChange(); }
        }
        public bool BackupserverLinkState
        {
            get { return _backupserverLinkState; }
            set { _backupserverLinkState = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 主服务器是否正常运作
        /// </summary>
        public bool MainSeverNormalFlag
        {
            get { return _mainServerNormalFlag; }
            set { _mainServerNormalFlag = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 主服务器心跳时间
        /// </summary>
        public string MainserverHeartTime
        {
            get { return _mainserverHeartTime; }
            set { _mainserverHeartTime = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 备用服务器心跳时间
        /// </summary>
        public string BackupserverHeartTime
        {
            get { return _backupserverHeartTime; }
            set { _backupserverHeartTime = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 是否正在通讯控制器
        /// </summary>
        public bool IsRunning
        {
            get { return _isRunning; }
            set { _isRunning = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 是否正在等待通讯【主服务器 等待 备用服务器停止】
        /// </summary>
        public bool IsWaitting
        {
            get { return _isWaiting; }
            set { _isWaiting = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 是否正在停止通讯线程
        /// </summary>
        public bool IsStopping
        {
            get { return _isStopping; }
            set { _isStopping = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 是否显示心跳日志
        /// </summary>
        public bool IsShowHeartBeatLog
        {
            get { return _isShowHeartBeatLog; }
            set { _isShowHeartBeatLog = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 是否检查各个线程的通讯心跳
        /// </summary>
        public bool IsCheckTaskHeartBeat
        {
            get { return _isCheckTaskHeartBeat; }
            set { _isCheckTaskHeartBeat = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 当前运行人员为
        /// </summary>
        public string CurrentMember
        {
            get { return _currentMember; }
            set { _currentMember = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 运行日志
        /// </summary>
        public AsyncObservableCollection<BasicLogModel> RunLogModels
        {
            get { return _runLogModels; }
            set { _runLogModels = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 各通讯线程的运行情况
        /// </summary>
        public Dictionary<int, Model.TestFunctionModel.TaskStartModel> DicTaskStation
        {
            get { return _dicTaskStation; }
            set { _dicTaskStation = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 各通讯线程的运行情况
        /// </summary>
        public Dictionary<string, Model.ConfigModel.RealTimeModel.RealTimeGasPotencyModel> RealTimeGasPotencyModels
        {
            get { return _realTimeGasPotencyModels; }
            set { _realTimeGasPotencyModels = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 各个探测器上一次的状态，用于处理告警记录的保存
        /// </summary>
        public Dictionary<string, Model.ConfigModel.GasMeter.AlarmSearchModel> DicGasState
        {
            get { return _dicGasState; }
            set { _dicGasState = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 工控机模式的配置
        /// </summary>
        public Dictionary<int,string> ClientModelPortDic
        {
            get { return _clientModelPortDic; }
            set { _clientModelPortDic = value; OnPropertyChange(); }
        }
        #region 配置类
        public ObservableCollection<Model.ConfigModel.SerialPort.EquipSerialPortModel> EquipSerialPorts
        {
            get { return _equipSerialPorts; }
            set { _equipSerialPorts = value; OnPropertyChange(); }
        }
        public ObservableCollection<Model.ConfigModel.Controller.ControllerConfigModel> ControllerConfigModel
        {
            get { return _controllerConfigModel; }
            set { _controllerConfigModel = value; OnPropertyChange(); }
        }
        public ObservableCollection<Model.ConfigModel.GasMeter.GasMeterConfig> GasMeterConfig
        {
            get { return _gasMeterConfig; }
            set { _gasMeterConfig = value; OnPropertyChange(); }
        }
        public ObservableCollection<UserInfo> TaskUserInfoModels
        {
            get { return _taskUserInfoModels; }
            set { _taskUserInfoModels = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 在线设备集合
        /// </summary>
        public AsyncObservableCollection<Model.ConfigModel.BasicSystemInfo.UserInfo> OnLineClientList
        {
            get { return _onLineClientList; }
            set { _onLineClientList = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 错误任务线程集合
        /// </summary>
        public List<int> ErrorTaskList
        {
            get { return _errorTaskList; }
            set { _errorTaskList = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 错误集合数量
        /// </summary>
        public int ErrorTaskListCount
        {
            get { return _errorTaskListCount; }
            set { _errorTaskListCount = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 开启通讯的配置整合模型
        /// </summary>
        public ObservableCollection<Model.TestFunctionModel.TaskStartModel> TaskStartModels
        {
            get { return _taskStartModels; }
            set { _taskStartModels = value; OnPropertyChange(); }
        }


        #endregion
        #endregion
        #region Public Function
        public void Init()
        {
            PublicHelper.ShowMsgEvent -= PublicHelper_ShowMsgEvent;
            PublicHelper.ShowMsgEvent += PublicHelper_ShowMsgEvent;
            //判断运行人员
            if (LocalConfig.IsMainServer)
            {
                CurrentMember = "[主服务器]";


            }
            else
            {
                CurrentMember = "[备用服务器]";
            }
            //连接数据库
            bool dbLinkFlag = DataBaseHelper.OpenDataBase(LocalConfig.ServerIp);
            ServerLinkState = dbLinkFlag;
            AddLogModel("连接主服务器数据库" + (dbLinkFlag ? "成功" : "失败"));
            //如果是工控机模式
            if (MainViewModel.Instance.LocalConfig.IsClientModel)
            {
                LoadCommunicationConfig();
                MainViewModel.Instance.ClientModelPortDic = new Dictionary<int, string>();
                //工控机模式
                RunOpenClentConfigViewEvent();
                //加载有多少个总线的配置
                //分配串口号
                //记录
            }
            if (LocalConfig.IsContainerBackUpServer)
            {
                bool backupdbLinkFlag = DataBaseHelper.linkBackUpServer(LocalConfig.BackUpserverIp);
                AddLogModel("连接备用服务器数据库" + (backupdbLinkFlag ? "成功" : "失败"));

                BackupserverLinkState = backupdbLinkFlag;
            }
            else
            {
                BackupserverLinkState = false;
            }
            #region 静态变量赋值
            Utility.Const.GbUnit.IsCalcStateByMannual = LocalConfig.IsPcCalcPGasMeterState;
            Utility.Const.GbUnit.IsO2defaultOK = LocalConfig.IsO2defaultOk;
            //IsO2defaultOK
            #endregion
            if (dbLinkFlag)//连接数据库成功
            {
                MainServerIsShutDown = false;
                //① 读取数据库配置
                //通讯配置
                //控制器配置
                //探测器配置
                LoadCommunicationConfig();

                if (LocalConfig.IsAutoRun)
                {
                    Task.Factory.StartNew(() =>
                    {
                        StartWork();
                    });

                }

            }
            else
            {

            }

        }
        /// <summary>
        /// 加载数据的配置，通讯端口，控制器，探测器
        /// </summary>
        public void LoadCommunicationConfig()
        {
            int controllerIndex = 0;
            int channalIndex = 0;
            int totalLine = 0;
            try
            {

                var PortConfig = DataBaseHelper.FindModelCol<Model.ConfigModel.SerialPort.EquipSerialPortModel>("EquipPortConfig");//通讯端口
                var controllerConfig = DataBaseHelper.FindModelCol<Model.ConfigModel.Controller.ControllerConfigModel>("ControllerModelList");//控制器配置
                var gasMeterConfig = DataBaseHelper.FindModelCol<Model.ConfigModel.GasMeter.GasMeterConfig>("GasMeterConfigList");//探测器端口
                var userConfig = DataBaseHelper.FindModelCol<Model.ConfigModel.BasicSystemInfo.UserInfo>("UserInfoData");//人员配置
                EquipSerialPorts = PortConfig;
                ControllerConfigModel = controllerConfig;
                GasMeterConfig = gasMeterConfig;
                ObservableCollection<Model.TestFunctionModel.TaskStartModel> taskStartModels = new ObservableCollection<Model.TestFunctionModel.TaskStartModel>();
                foreach (var model in EquipSerialPorts)
                {
                    Model.TestFunctionModel.TaskStartModel tmpModel = new Model.TestFunctionModel.TaskStartModel();

                    if (model.ConfigType != "其他设备")
                    {
                        tmpModel = new Model.TestFunctionModel.TaskStartModel()
                        {
                            TaskIndex = taskStartModels.Count + 1,
                            TotalLineNo = model.TotalLineNumber,
                            SerialPortCom = model.SerialPortName,
                            TaskStattion = false,
                            Baud = model.BoardRate,
                            WaitTime = model.WaitTime,
                            Dic_Controller = new Dictionary<int, Model.ConfigModel.Controller.TaskControllerModel>()

                        };//添加基本配置
                        foreach (var c_Model in ControllerConfigModel)
                        {
                            if (int.Parse(c_Model.TotalLineNumber) == model.TotalLineNumber)
                            {

                                tmpModel.Dic_Controller.Add(c_Model.ControllerAddress, new Model.ConfigModel.Controller.TaskControllerModel()
                                {
                                    Address = c_Model.ControllerAddress,
                                    ChannelCount = c_Model.ControllerChannalNumber,
                                    Factory = c_Model.ControllerFactory,
                                    Dic_GasMeter = new Dictionary<int, Model.ConfigModel.GasMeter.TaskGasMeterModel>()
                                });//添加控制器配置
                                foreach (var g_model in GasMeterConfig)
                                {
                                    if (g_model.TotalLineNumber == model.TotalLineNumber && g_model.ControllerAddress == c_Model.ControllerAddress)
                                    {

                                        controllerIndex = c_Model.ControllerAddress;
                                        channalIndex = g_model.ChannalId;
                                        totalLine = model.TotalLineNumber;
                                        if (totalLine == 4)
                                        {
                                            Console.WriteLine("");
                                        }
                                        tmpModel.Dic_Controller[c_Model.ControllerAddress].Dic_GasMeter.Add(g_model.ChannalId, new Model.ConfigModel.GasMeter.TaskGasMeterModel()
                                        {
                                            ChannelIndex = g_model.ChannalId,
                                            GasType = ((Model.DataEnum.Enum_GasType)g_model.GasType).ToString(),
                                            HighAlarmValue = g_model.HighAlarmPoint,
                                            LowAlarmValue = g_model.LowAlarmPoint,
                                            Area = g_model.GasMeterAreaLocation,
                                            ChildArea = g_model.ChildAreaName,
                                            Postion = g_model.GasSettingLocation,
                                            Unit = g_model.GasUnit.ToString(),
                                            Range = g_model.GasRange.ToString(),
                                            StartRange = g_model.startRange.ToString(),
                                            EndRange = g_model.endRange.ToString(),
                                            SerialNo = g_model.GasMeterSerialNo,
                                            IsUse = g_model.IsUseFlag
                                        });//添加探头配置
                                    }
                                }
                            }
                        }
                    }
                    else {
                        continue;
                    }
                    taskStartModels.Add(tmpModel);
                }
                TaskStartModels = taskStartModels;
                TaskUserInfoModels = userConfig;

                readRealTimeModel();


            }
            catch (Exception ex)
            {
                Utility.Helper.PublicHelper.WriteErrorMsg("[" + controllerIndex + "]--[" + channalIndex + "]" + ex);

            }
        }
        private void readRealTimeModel()
        {
            //读取实时数据库，用于在后续更新数据的时候，只要数据一致，则不更新
            RealTimeGasPotencyModels = new Dictionary<string, RealTimeGasPotencyModel>();
            var gasRealTimePotencyModels = DataBaseHelper.FindModelCol<Model.ConfigModel.RealTimeModel.RealTimeGasPotencyModel>("RealTimeGasPotencyData");
            foreach (var k in gasRealTimePotencyModels)
            {
                if (RealTimeGasPotencyModels.ContainsKey(k.GasSerialNo) == false)
                {
                    RealTimeGasPotencyModels.Add(k.GasSerialNo, k);
                }
            }
        }
        private void PublicHelper_ShowMsgEvent(object sender, EventArgs e)
        {
            AddLogModel(sender.ToString());
        }

        public void StartWork()
        {
            //心跳监听线程
            Task.Factory.StartNew(() =>
            {
                heartBeatRun();
            });
            if (LocalConfig.IsMainServer)//主服务器
            {

                if (LocalConfig.IsContainerBackUpServer)
                {
                    //包含备用服务器
                    //判断备用服务器是否正在运行
                    int backupServerState = readServerRunState(false);
                    if (backupServerState == 0)//未启动
                    {
                        //直接运行通讯线程
                        StartTaksEvent(null, new EventArgs());
                        setServerRunState(true, 1);

                    }
                    else if (backupServerState == 1)//通讯中
                    {
                        //置位状态，告知备用服务器停止通讯，转换为主站通讯
                        IsWaitting = true;
                    }
                    else if (backupServerState == 2)//监听中
                    {
                        //直接运行通讯线程
                        StartTaksEvent(null, new EventArgs());
                        setServerRunState(true, 1);

                    }
                }
                else
                {
                    //不包含备用服务器，直接运行通讯方法
                    StartTaksEvent(null, new EventArgs());
                    setServerRunState(true, 1);
                }
            }
            else //备用服务器
            {
                //备用服务器通讯动作线程
                Task.Factory.StartNew(() =>
                {
                    communicateRun();
                });
            }

        }

        public void ChangeAutoO2State(bool changeValue=false)
        {
            Utility.Const.GbUnit.IsO2defaultOK = changeValue;
        }
        #region LogModelFunction
        private int _showLogControllerTotalLine;
        private int _showLogControllerAddressIndex;
        private bool _isShowCommunication;
        private bool _isSaveLog;
        /// <summary>
        /// 显示通讯日志的控制器总线号
        /// </summary>
        public int ShowLogControllerTotalLine
        {
            get { return _showLogControllerTotalLine; }
            set { _showLogControllerTotalLine = value;
                Utility.Const.GbUnit.ShowLogControllerTotalLine = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 显示通讯日志的控制器地址
        /// </summary>
        public int ShowLogControllerAddressIndex
        {
            get { return _showLogControllerAddressIndex; }
            set {
                _showLogControllerAddressIndex = value;
                Utility.Const.GbUnit.ShowLogControllerAddressIndex = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 是否显示通讯日志
        /// </summary>
        public bool IsShowCommunication
        {
            get { return _isShowCommunication; }
            set {
                _isShowCommunication = value;
                Utility.Const.GbUnit.IsShowCommunicationLog = value; OnPropertyChange(); }
        }
        /// <summary>
        /// 是否保存通讯日志
        /// </summary>
        public bool IsSaveLog
        {
            get { return _isSaveLog; }
            set
            {
                _isSaveLog = value;
                OnPropertyChange();
            }
        }
        /// <summary>
        /// 添加日志
        /// </summary>
        /// <param name="msg"></param>
        public void AddLogModel(string msg)
        {
            try
            {
                if (RunLogModels == null) RunLogModels = new AsyncObservableCollection<BasicLogModel>();
                lock (LogLockHelper)
                {
                    RunLogModels.Add(new BasicLogModel()
                    {
                        LogIndex = RunLogModels.Count + 1,
                        LogTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        LogMsg = msg
                    });

                }

                if (RunLogModels.Count > 150)
                {
                    RunLogModels.Clear();
                }
                PublicHelper.WriteMsg(msg);
            }
            catch (Exception ex)
            {
                PublicHelper.WriteErrorMsg(ex);
            }

        }
        #endregion
        #endregion
        #region private Function
        #region 心跳监测
        List<object> selectKey = new List<object>();
        List<object> selectValue = new List<object>();
        List<object> updateKey = new List<object>();
        List<object> updateValue = new List<object>();
        private bool isDeleting = false;
        private bool _startDelData = false;
        public bool IsDeleting
        {
            get { return isDeleting; }
            set { isDeleting = value; OnPropertyChange("IsDeleting"); }
        }
        public bool StartDelData
        {
            get { return _startDelData; }
            set { _startDelData = value; OnPropertyChange("StartDelData"); }
        }
        /// <summary>
        /// 心跳线程
        /// </summary>
        private void heartBeatRun()
        {
            _heartBeatCheckSplit = LocalConfig.HeartBeatCheckSplit ;
            setServerRunState(LocalConfig.IsMainServer, 2);
            while (true)
            {
                updateHeartBeatState();
                _heartBeatCheckSplit--;
                if (IsShowHeartBeatLog) AddLogModel("更新心跳");
                if (IsStopping&&IsMainServer==false)//备用服务器 监听到主服务器上线 停止通讯中
                {
                    IsStopping = false;
                    foreach (var k in DicTaskStation)
                    {
                        if(k.Value.TaskStattion==true)
                        {
                            IsStopping=true;
                            AddLogModel(CurrentMember + "监听到主服务器上线 停止通讯中"+k.Value.TaskIndex);
                           
                            break;
                        }
                    }
                    if (IsStopping == false)
                    {
                        if (Utility.Helper.DataBaseHelper.CheckMainDBLinkState() == false)
                        {
                            //如果主服务器刚刚是连接不上的情况，尝试去连接一次
                            Utility.Const.GbUnit.DatabaseLinkSuccessFlag = true;
                        }
                        AddLogModel(CurrentMember+"所有通讯线程已经停止");
                        IsRunning = false;
                        setServerRunState(IsMainServer, 2);
                    }
                }
                if (Utility.Const.GbUnit.reloadRealTimeModelFlag)
                {
                    readRealTimeModel();
                    Utility.Const.GbUnit.reloadRealTimeModelFlag = false;
                }
                if (IsWaitting && IsMainServer)//主服务器等待 备用服务器 停止通讯
                { 
                    //检测备用服务器是否停止
                    if(readServerRunState(false)==2|| readServerRunState(false) == 0)
                    {
                        IsWaitting = false;
                        AddLogModel("备用服务器已经停止所有通讯线程");
                        AddLogModel(CurrentMember + "即将开启通讯线程");
                        StartTaksEvent(null, new EventArgs());
                        setServerRunState(IsMainServer, 1);
                    }
                }
                if (_heartBeatCheckSplit == 0)
                {
                    updateClientHeartBeatModel();
                    _heartBeatCheckSplit = LocalConfig.HeartBeatCheckSplit;
                    checkHeartBeatState();
                    if (IsCheckTaskHeartBeat)
                        checkTaskHeartBeat();
                    if (IsShowHeartBeatLog)
                        AddLogModel("检查心跳");
                    if(IsNeedReloadConfig)
                    {
                        if (IsMainServer)//主要服务器
                        {
                            if (readServerRunState(true) == 1)
                            {
                                //1.停止通讯线程
                                StopTaksEvent(null, new EventArgs());
                                //2.等待所有通讯线程结束
                                IsStartCheckToReStart = true;

                                setServerRunReLoad(IsMainServer, false);
                                IsNeedReloadConfig=false;
                            }
                          
                        }
                        else//备用服务器
                        {
                            if (readServerRunState(true) != 1|| readServerRunState(false) == 1)//主服务器没有在通讯，备用服务器通讯中
                            {
                                //1.停止通讯线程
                                StopTaksEvent(null, new EventArgs());
                                //2.等待所有通讯线程结束
                                IsStartCheckToReStart = true;

                                setServerRunReLoad(IsMainServer, false);
                                IsNeedReloadConfig = false;

                            }
                        }
                      
                    }
                }
                if (IsStartCheckToReStart)
                {
                    bool isAllStop = true;
                    foreach (var k in DicTaskStation)
                    {
                        if (k.Value.TaskStattion == true)
                        {
                            isAllStop = false;
                            AddLogModel(CurrentMember + "监听到"+ CurrentMember + "需要重新加载配置 停止通讯中" + k.Value.TaskIndex);

                            break;
                        }
                    }
                    if (isAllStop == true)
                    {
                        AddLogModel(CurrentMember + "所有通讯线程已经停止");
                        //3.重新加载配置
                        AddLogModel(CurrentMember + "重新加载配置");

                        LoadCommunicationConfig();

                        //4.重新开启通讯线程
                        AddLogModel(CurrentMember + "重新开启通讯线程");

                        StartTaksEvent(null, new EventArgs());
                        setServerRunState(IsMainServer, 1);
                        IsStartCheckToReStart = false;
                    }
                }
            
                 checkHistoryDataDelete();
         
            

                Thread.Sleep(1000);
            }
        }
        /// <summary>
        /// 更新心跳时间
        /// </summary>
        private void updateHeartBeatState()
        {

            selectKey = new List<object>();
            selectValue = new List<object>();
            updateKey = new List<object>();
            updateValue = new List<object>();
            selectKey.Add("ServerType");
            if (LocalConfig.IsMainServer)
            {
                selectValue.Add("主服务器");
            }
            else
            {
                selectValue.Add("备用服务器");
            }


            updateKey.Add("ServerMsg");
            updateValue.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            Utility.Helper.DataBaseHelper.UpDateModel<Model.ConfigModel.BasicSystemInfo.HeartBeatModel>("HeartBeatModel", selectKey, selectValue, updateKey, updateValue);

     
        }
        List<object> HeartselectKey = new List<object>();
        List<object> HeartselectValue = new List<object>();
        List<object> HeartupdateKey = new List<object>();
        List<object> HeartupdateValue = new List<object>();
        /// <summary>
        /// 更新与从站交互的通讯心跳
        /// </summary>
        private void updateClientHeartBeatModel()
        {
            try
            {
                if ((IsMainServer && readServerRunState(true) == 1))
                {
                    #region  更新与从站交互的通讯心跳

                    foreach (var k in TaskUserInfoModels)
                    {
                        HeartselectKey = new List<object>();
                        HeartselectValue = new List<object>();
                        HeartupdateKey = new List<object>();
                        HeartupdateValue = new List<object>();

                        HeartselectKey.Add("UserName");
                        HeartselectValue.Add(k.UserName);
                        HeartupdateKey.Add("ServerHeartBeat");
                        HeartupdateValue.Add(DateTime.Now.ToString("yyyyMMddHHmmss"));
                        Utility.Helper.DataBaseHelper.UpDateModel<Model.ConfigModel.BasicSystemInfo.HeartBeatModel>("GasUserRunningState", HeartselectKey, HeartselectValue, HeartupdateKey, HeartupdateValue);

                    }
                    #endregion
                }

                var clientModel = DataBaseHelper.FindModelCol<Model.ConfigModel.BasicSystemInfo.RunningStateModel>("GasUserRunningState");
                //判断在线设备
                foreach (var k in clientModel)
                {
                    DateTime clienTime;
                    if (DateTime.TryParse(k.ClientHeartBeat, out clienTime))
                    {
                        if (compareTime(DateTime.Now, clienTime, 60))
                        {
                            if (OnLineClientList == null) OnLineClientList = new AsyncObservableCollection<UserInfo>();
                            bool containFlag = false;
                            foreach (var user in OnLineClientList)
                            {
                                if (user.UserName == k.UserName)
                                {
                                    containFlag = true;
                                }
                            }
                            if (containFlag)
                            {

                            }
                            else
                            {
                                OnLineClientList.Add(new UserInfo()
                                {
                                    UserName = k.UserName,
                                });
                            }
                        }
                        else
                        {
                          

                            if (OnLineClientList == null) OnLineClientList = new AsyncObservableCollection<UserInfo>();
                            bool containFlag = false;
                            int removeIndex = 0;
                            foreach (var user in OnLineClientList)
                            {
                                if (user.UserName == k.UserName)
                                {
                                    containFlag = true;
                                    break;
                                }
                                removeIndex++;
                            }
                            if (containFlag)
                            {
                                AddLogModel("["+ k.UserName + "]"+"下线");
                                OnLineClientList.RemoveAt(removeIndex);
                            }

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Utility.Helper.PublicHelper.WriteErrorMsg(ex);
            }
           
          
        }
        /// <summary>
        /// 设置心跳模型中，服务器状态
        /// </summary>
        /// <param name="isMain"></param>
        /// <param name="isRun">0 未运行 1 通讯中  2监听中</param>
        private void setServerRunState(bool isMain, int isRun)
        {
            selectKey = new List<object>();
            selectValue = new List<object>();
            updateKey = new List<object>();
            updateValue = new List<object>();
            selectKey.Add("ServerType");
            if (isMain)
            {
                selectValue.Add("主服务器");
            }
            else
            {
                selectValue.Add("备用服务器");
            }


            updateKey.Add("ServerIsRunning");
            updateValue.Add(isRun);
            Utility.Helper.DataBaseHelper.UpDateModel<Model.ConfigModel.BasicSystemInfo.HeartBeatModel>("HeartBeatModel", selectKey, selectValue, updateKey, updateValue);
        }
        /// <summary>
        /// 复位重新加载配置标志
        /// </summary>
        /// <param name="isMain"></param>
        /// <param name="isRun">true 需要重新加载  false 已经加载完毕</param>
        private void setServerRunReLoad(bool isMain, bool isRun)
        {
            selectKey = new List<object>();
            selectValue = new List<object>();
            updateKey = new List<object>();
            updateValue = new List<object>();
            selectKey.Add("ServerType");
            if (isMain)
            {
                selectValue.Add("主服务器");
            }
            else
            {
                selectValue.Add("备用服务器");
            }


            updateKey.Add("IsNeedReloadConfig");
            updateValue.Add(isRun);
            Utility.Helper.DataBaseHelper.UpDateModel<Model.ConfigModel.BasicSystemInfo.HeartBeatModel>("HeartBeatModel", selectKey, selectValue, updateKey, updateValue);
        }
        /// <summary>
        /// 读取心跳模型
        /// </summary>
        /// <param name="isMain"></param>
        /// <returns></returns>
        private int readServerRunState(bool isMain)
        {
            int result = 0;
            CurHeartBeatModels = Utility.Helper.DataBaseHelper.FindModelCol<HeartBeatModel>("HeartBeatModel");
            foreach (var k in CurHeartBeatModels)
            {
                if (k.ServerType == (isMain ? "主服务器" : "备用服务器"))
                {
                    result = k.ServerIsRunning;
                    break;
                }
            }
            return result;
        }
        /// <summary>
        /// 检查心跳模型
        /// </summary>
        private void checkHeartBeatState()
        {
            CurHeartBeatModels = DataBaseHelper.FindModelCol<HeartBeatModel>("HeartBeatModel");
            if (LocalConfig.IsContainerBackUpServer)
            {

                if (IsMainServer && LocalConfig.IsContainerBackUpServer)//主服务器，并且包括备用服务器时
                {
                    foreach (var k in CurHeartBeatModels)
                    {
                        if (k.ServerType == "备用服务器")
                        {

                            DateTime msgTime;
                            if (DateTime.TryParse(k.ServerMsg, out msgTime))
                            {
                                if (compareTime(DateTime.Now, msgTime, LocalConfig.MaxHeartBeatSecond))
                                {

                                    _backupServerFailTime = 0;
                                }
                                else
                                {

                                    if (_backupServerFailTime <= 3)
                                    {
                                        _backupServerFailTime++;
                                        AddLogModel(string.Format("第{0}次,监测到备用服务器心跳没刷新", _backupServerFailTime));
                                        if (_backupServerFailTime == 3)
                                        {
                                            AddLogModel(string.Format("备用服务器心跳没刷新超过最大次数"));
                                            setServerRunState(false, 0);
                                        }
                                    }
                                }
                            }
                            BackupserverHeartTime = k.ServerMsg;
                        }
                        else if (k.ServerType == "主服务器")
                        {
                            IsNeedReloadConfig = k.IsNeedReloadConfig;
                            MainserverHeartTime = k.ServerMsg;

                        }
                    }
                }
                else if (IsMainServer == false)
                {
                    //如果是备用服务器，监听主站的信条日期是否是最近的30s

                    foreach (var k in CurHeartBeatModels)
                    {
                        if (k.ServerType == "主服务器")
                        {
                            IsNeedReloadConfig = k.IsNeedReloadConfig;
                            DateTime msgTime;
                            if (DateTime.TryParse(k.ServerMsg, out msgTime))
                            {
                                if (compareTime(DateTime.Now, msgTime, LocalConfig.MaxHeartBeatSecond))
                                {
                                    _mainServerFailTime = 0;
                                    AddLogModel(string.Format("主服务器正常运行"));

                                    MainSeverNormalFlag = true;

                                }
                                else
                                {
                                    _mainServerFailTime++;
                                    if (_mainServerFailTime <= 3)
                                    {

                                        AddLogModel(string.Format("第{0}次,监测到主服务器心跳没刷新", _mainServerFailTime.ToString()));
                                        if (_mainServerFailTime == 3)
                                        {
                                            AddLogModel(string.Format("主服务器心跳没刷新超过最大次数，准备启动备用服务器"));
                                            MainSeverNormalFlag = false;

                                        }
                                    }
                                    else if (_mainServerFailTime == 12)
                                    {
                                        setServerRunState(true, 0);//将主服务器状态置位置为未运行
                                    }
                                }
                            }
                            MainserverHeartTime = k.ServerMsg;

                        }
                        else if (k.ServerType == "备用服务器")
                        {
                            IsNeedReloadConfig = k.IsNeedReloadConfig;
                            BackupserverHeartTime = k.ServerMsg;

                        }
                    }
                }
            }
            else
            {
                foreach (var k in CurHeartBeatModels)
                {
                    if (k.ServerType == "主服务器")
                    {
                        IsNeedReloadConfig = k.IsNeedReloadConfig;
                        MainserverHeartTime = k.ServerMsg;

                    }
                }
            }
           

        }
        /// <summary>
        /// 删除历史数据
        /// </summary>
        private void checkHistoryDataDelete()
        {
            if ((IsMainServer && readServerRunState(true) == 1) || (IsMainServer == false && readServerRunState(true) != 1 && readServerRunState(false) == 1))
            {
                var nowTime = DateTime.Now;
                int delHour = LocalConfig.DelHistoryHour;
                if ((nowTime.Hour == delHour && nowTime.Minute == 1 && nowTime.Second >= 10 && nowTime.Second <= 30&& IsDeleting==false) || (StartDelData == true&& IsDeleting==false))
                {
                    IsDeleting = true;
                    Task.Factory.StartNew(() =>
                    {
                        AddLogModel("准备清除历史数据");
                        DeleteHistoryData(LocalConfig.DataSaveMaxDay);
                        AddLogModel("清除历史数据完毕");
                        System.Threading.Thread.Sleep(1000);
                        IsDeleting = false;
                    });
                        AddLogModel("清除历史数据现场已经开启");

                 
                }
                StartDelData = false;
            }
         
        }
        /// <summary>
        /// 清空历史数据，保留最大保存时间内的数据
        /// </summary>
        /// <param name="lastDay"></param>
        public void DeleteHistoryData(int lastDay)
        {
            try
            {
                if (lastDay == 0) return;
                DateTime deleteDate = DateTime.Now.AddDays(lastDay * -1);
                //探头数据
                for (int i = 0; i < GasMeterConfig.Count; i++)
                {
                    var tmpGasModel = GasMeterConfig[i];
                    string collectionName = tmpGasModel.GasMeterSerialNo;
                    //Utility.Helper.DataBaseHelper.DeleteHistoryData(collectionName, "OccurTime", deleteDate);
                    Utility.Helper.DataBaseHelper.DeleteHistoryData(collectionName, "OccurTime", deleteDate);
                    AddLogModel("正在清除[" + collectionName + "]历史数据");
                    System.Threading.Thread.Sleep(100);
                    updateHeartBeatState();
                }
                //高警记录
                AddLogModel("正在清除告警记录历史数据");
                Utility.Helper.DataBaseHelper.DeleteHistoryData("GasMeterAlarmData", "StartTime", deleteDate);


            }
            catch (Exception ex)
            {
                Utility.Helper.PublicHelper.WriteErrorMsg(ex);
            }
        }
        /// <summary>
        /// 检查每个线程的通讯心跳
        /// 通过线程的开始时间判定是否有在持续通讯
        /// </summary>
        private void checkTaskHeartBeat()
        {
            ErrorTaskList = new List<int>();
            if (CommunicationLogViewModel.Instance.CurrentRunStateModels != null)
            {
                foreach (var k in CommunicationLogViewModel.Instance.CurrentRunStateModels)
                {
                    if (k.IsRun)
                    {
                        DateTime taskStartTime = Convert.ToDateTime(k.StartTime);
                        if (compareTime(DateTime.Now, taskStartTime, 60) == false)
                        {
                            AddLogModel("总线:" + k.TaskIndex + "通讯异常，停止在" + k.StartTime.ToString() + "--" + k.CurrentStep + "-" + k.CurrentReadPotencyStep);
                            ErrorTaskList.Add(k.TaskIndex);
                        }

                    }
                }
                ErrorTaskListCount = ErrorTaskList.Count;
            }
           
        }
        /// <summary>
        /// 判断另外一台服务器是否在心跳相应时间内
        /// </summary>
        /// <param name="dt1"></param>
        /// <param name="dt2"></param>
        /// <param name="compareSecond"></param>
        /// <returns></returns>
        private bool compareTime(DateTime dt1, DateTime dt2, int compareSecond)
        {
            bool result = false;
            TimeSpan timeSpan = dt2 - dt1;
            if (Math.Abs(timeSpan.TotalSeconds) <= compareSecond)
            {
                result = true;
            }
            return result;
        }
        #endregion
        #region 通讯线程
        private void communicateRun()
        {

            while (true)
            {
                if (MainSeverNormalFlag && IsRunning==false)
                {
                    //主服务器正常运行中
                }
                else if(MainSeverNormalFlag&& IsRunning&& IsStopping==false) {
                    //主服务器正常运行中
                    _mainServerState = readServerRunState(true);
                    if (_mainServerState == 2)
                    {
                        AddLogModel("检测到主服务器重新上线");
                        AddLogModel("即将停止当前服务器通讯线程");
                        StopTaksEvent(null, new EventArgs());
                        IsStopping = true;
                        //等待全部线程退出
                    }
                }
                else
                {
                    if (IsRunning == false)
                    {
                        //主服务器异常运行中，备用服务器顶上
                        AddLogModel("检测到主服务器没有更新心跳，【备用服务器】准备开启设备通讯");
                        StartTaksEvent(null, new EventArgs());
                        IsRunning = true;
                        setServerRunState(false, 1);
                    }
                    else
                    {
                        //备用服务器运行中，监测主站服务是否启动了
                        
                    }


                }

                if (ExitFlag)
                {
                    AddLogModel("退出通讯线程");
                    break;
                }
                Thread.Sleep(1000);
            }
        }
        #endregion 
        #endregion
    }
}
